// 加载配置
var GraceRequestConfig = require('@/utils/request/config.js');
var md5 = require('@/utils/md5.js');
var state = require('@/config.js');
var grace = require('@/utils/grace.js');

// 核心工具定义
module.exports = {

	// token 数据记录
	token: '',


	// 连接接服务器获得请求 token
	getTokenFromApi: function(resolve, reject) {
		new Promise(GraceRequestConfig.getToken).then((res) => {
			this.token =
				`${res.token_type.toLowerCase().replace(/( |^)[a-z]/g,(L)=>L.toUpperCase())} ${res.access_token}`;

			state.storage(state.storageName, res)
			// 将 token 保存在本地并记录获取时间
			uni.setStorageSync(GraceRequestConfig.localTokenKeyName, this.token);
			// 记录时间
			var dateObj = new Date();
			var cTime = dateObj.getTime();
			cTime += '';
			uni.setStorageSync('GraceRequestTokenTime', cTime);
			state.isLogin(true);
			resolve();
		}).catch((res) => {
			this.debug('api 获取 token 失败');
			this.token = '';
			state.isLogin(false);
			reject(res);
		});
	},

	// 获取 token
	getToken: function(resolve, reject, login) {
		// 首先尝试从本地获取
		var token = uni.getStorageSync(GraceRequestConfig.localTokenKeyName);
		// 本地不存在 token 数据
		if (!token || token == '') {
			state.loginOut();
			state.isLogin(false);
		} else {
			this.token = token;
		}

		resolve(true);

	},

	// 设置默认值补齐
	requestInit: function(sets, withLoginToken, type) {
		if (!sets.data) {
			sets.data = {};
		}
		if (!sets.header) {
			sets.header = {
				'content-type': type == 1 ? GraceRequestConfig.getHeaderDefault : GraceRequestConfig
					.postHeaderDefault,
			};
		}

		// sets.header['VERSION'] = 'xyy'; //开发时请求头加版本号

		if (!sets.timeout) {
			sets.timeout = 60000;
		}
		if (!sets.dataType) {
			sets.dataType = 'json';
		}

		if (!sets.header.Authorization) {
			sets.header.Authorization = this.token;
		}


		if (withLoginToken) {
			var loginToken = this.checkLogin();
			if (loginToken) {
				sets.header.logintoken = loginToken;
			}
		}

		return sets;
	},

	// 服务端 token 错误处理
	tokenErrorHandle: function(res, fail) {
		var that = this;
		switch (res.statusCode) {
			case 401:
				state.loginOut();
				state.isLogin(false);
				// 关闭加载
				that.pageLoading = true;
				if (res.data.msg.indexOf("不存在") > 0 || res.data.msg.indexOf("Not Found") > 0) {
					uni.showModal({
						title: '温馨提示',
						content: '根据湖南省XXXX003相关规定，您需要先到管理平台hnxxpt.zgzjzj.net进行注册才可以登录学习。',
						showCancel: false,
						confirmText: '我知道了',
						success: function(res) {

						}
					});
				} else if (res.data.msg.indexOf("未同步") > 0 || res.data.msg.indexOf("UnSynchronized") > 0) {
					uni.showModal({
						title: '温馨提示',
						content: '根据湖南省XXXX003相关规定，为保证您的培训学时可以正常出具证书，您需要先使用电脑进入管理平台：hnxxpt.zgzjzj.net进行学员登录，登录成功后点击培训入口中的“XXXX002”进行页面跳转，以完成账号信息同步，同步完成后即可直接在"XXXX002”培训平台登录。',
						showCancel: false,
						confirmText: '我知道了',
						success: function(res) {

						}
					});
				} else if (res.data.msg.indexOf("锁定") > -1 || res.data.msg.indexOf("locked") > -1) {
					uni.showToast({
						title: res.data.msg,
						icon: "none",
						duration: 3000
					});
				} else if (state.officialLoginStatus == undefined || state.officialLoginStatus != 1) {
					uni.showToast({
						title: "登录超时，或帐号在其它地方登录。",
						icon: "none",
						duration: 3000,
						success: () => {
							setTimeout(function() {
								if (typeof fail === 'object') {
									fail.f(that.gotoLogin, '/pages/login/login',
										'redirect');
								} else {
									that.gotoLogin('/pages/login/login', 'redirect')
								}
							}, 3000);
						}
					});
				} else {
					state.officialLoginStatus = 2
				}
				break;
		}
	},

	// 服务端数据处理
	dataSuccess: function(res, sets, success, fail) {
		var that = this;
		this.debug(res);
		switch (res.statusCode) {
			case 200:
				if (res.data.msg && res.data.code == 1) {
					uni.showToast({
						title: res.data.msg,
						icon: "none"
					});
					fail(res.data)
				} else if (sets.dataPro) {
					success(res.data);
				} else {
					success(res.data.data);
				}
				break;
			case 500:
				uni.showToast({
					title: "网络错误500,请稍后重试",
					icon: "none"
				});
				break;
			default:
				if (res.data.error) {
					uni.showToast({
						title: res.data.error,
						icon: "none"
					});
				} else if (res.data.msg && res.data.code == 1) {
					if (res.data.msg.indexOf('用户凭证已过期') > -1) {
						uni.showToast({
							title: '自动登录中。。。',
							icon: "none"
						});
					} else {
						uni.showToast({
							title: res.data.msg,
							icon: "none"
						});
					}

				}
		}
		this.tokenErrorHandle(res, fail);
	},
	// 服务端数据处理
	dataSuccess2: function(res, sets, success, fail) {
		var that = this;
		this.debug(res);
		switch (res.statusCode) {
			case 200:
				if (res.data.code == 1 && res.data.data) {
					if (sets.dataPro) {
						success(res.data);
					} else {
						success(res.data.data);
					}
				} else {
					fail(res.data)
				}
				break;
			case 500:
				uni.showToast({
					title: "网络错误500,请稍后重试",
					icon: "none"
				});
				break;
			default:
				if (res.data.error) {
					uni.showToast({
						title: res.data.error,
						icon: "none"
					});
				} else if (res.data.msg && res.data.code == 1) {
					if (res.data.msg.indexOf('用户凭证已过期') > -1) {
						uni.showToast({
							title: '自动登录中。。。',
							icon: "none"
						});
					} else {
						uni.showToast({
							title: res.data.msg,
							icon: "none"
						});
					}

				}
		}
		this.tokenErrorHandle(res, fail);
	},
	// 服务端数据处理
	dataSuccess3: function(res, sets, success, fail) {
		var that = this;
		this.debug(res);
		switch (res.statusCode) {
			case 200:
				if (res.data.code == 0 && res.data.data) {
					if (sets.dataPro) {
						success(res.data);
					} else {
						success(res.data.data);
					}
				} else {
					fail(res.data)
				}
				break;
			case 500:
				uni.showToast({
					title: "网络错误500,请稍后重试",
					icon: "none"
				});
				break;
			default:
				if (res.data.error) {
					uni.showToast({
						title: res.data.error,
						icon: "none"
					});
				} else if (res.data.msg && res.data.code == 1) {
					if (res.data.msg.indexOf('用户凭证已过期') > -1) {
						uni.showToast({
							title: '自动登录中。。。',
							icon: "none"
						});
					} else {
						uni.showToast({
							title: res.data.msg,
							icon: "none"
						});
					}

				}
		}
		this.tokenErrorHandle(res, fail);
	},
	// GET 请求 异步
	get: function(url, sets, success, fail, complete, withLoginToken, tip) {
		if (!sets) {
			sets = {};
		}
		if (!success) {
			success = function(res) {}
		}
		if (!fail) {
			fail = function(e) {}
		}
		if (!complete) {
			complete = function(res) {}
		}
		if (!withLoginToken) {
			withLoginToken = false;
		}

		new Promise(this.getToken.bind(this)).then(() => {
			if (GraceRequestConfig.apiBaseUrl != '') {
				url = GraceRequestConfig.apiBaseUrl + url;
			}
			sets = this.requestInit(sets, withLoginToken, 1);
			uni.request({
				url: url,
				data: sets.data,
				timeout: sets.timeout,
				dataType: sets.dataType,
				header: sets.header,
				method: 'GET',
				success: (res) => {
					this.dataSuccess(res, sets, success, fail)
				},
				fail: (error) => {
					fail(error.errMsg);
				},
				complete: (res) => {
					if (!tip) {
						uni.hideLoading();
					}
					complete(res);
				}
			});
		}).catch((e) => {
			console.log(e);
			this.tokenError();
		});
	},
	// GET 请求 异步
	get2: function(url, sets, success, fail, complete, withLoginToken) {
		if (!sets) {
			sets = {};
		}
		if (!success) {
			success = function(res) {}
		}
		if (!fail) {
			fail = function(e) {}
		}
		if (!withLoginToken) {
			withLoginToken = false;
		}

		new Promise(this.getToken.bind(this)).then(() => {
			if (GraceRequestConfig.apiBaseUrl != '') {
				url = GraceRequestConfig.apiBaseUrl + url;
			}
			sets = this.requestInit(sets, withLoginToken, 1);
			uni.request({
				url: url,
				data: sets.data,
				timeout: sets.timeout,
				dataType: sets.dataType,
				header: sets.header,
				method: 'GET',
				success: (res) => {
					this.dataSuccess(res, sets, success, fail)
				},
				fail: (error) => {
					fail(error.errMsg);
				},
				complete: (res) => {
					if (!complete) {
						uni.hideLoading();
					} else {
						complete(res);
					}
				}
			});
		}).catch((e) => {
			console.log(e);
			this.tokenError();
		});
	},
	// GET 请求 同步
	getSync: async function(url, sets, withLoginToken) {
		let res, error;
		if (!withLoginToken) {
			withLoginToken = false;
		}
		return new Promise(this.getToken.bind(this)).then(async () => {
			if (GraceRequestConfig.apiBaseUrl != '') {
				url = GraceRequestConfig.apiBaseUrl + url;
			}
			sets = this.requestInit(sets, withLoginToken, 1);
			var [error, res] = await uni.request({
				url: url,
				data: sets.data,
				timeout: sets.timeout,
				dataType: sets.dataType,
				header: sets.header,
				method: 'GET'
			});
			if (error != null) {
				return false;
			}
			this.debug(res);
			this.tokenErrorHandle(res);
			return res.data.data;
		}).catch((e) => {
			console.log(e);
			this.tokenError();
			return ['', e];
		});
	},

	// POST 请求 异步
	post: function(url, sets, success, fail, complete, isSign, withLoginToken, tip) {
		if (!sets) {
			sets = {};
		}
		if (!success) {
			success = function(res) {}
		}
		if (!fail) {
			fail = function(e) {}
		}
		if (!complete) {
			complete = function(res) {}
		}
		if (!withLoginToken) {
			withLoginToken = false;
		}

		new Promise(this.getToken.bind(this)).then(() => {
			if (GraceRequestConfig.apiBaseUrl != '') {
				url = GraceRequestConfig.apiBaseUrl + url;
			}
			sets = this.requestInit(sets, withLoginToken, 2);
			if (!sets.header['content-type']) {
				sets.header['content-type'] = GraceRequestConfig.postHeaderDefault;
			}
			if (isSign == true) {
				sets.data = this.sign(sets.data);
			} else if (isSign == 'value') {
				sets.data = this.signValue(sets.data);
			}
			uni.request({
				url: url,
				data: sets.data,
				timeout: sets.timeout,
				dataType: sets.dataType,
				header: sets.header,
				method: 'POST',
				success: (res) => {
					this.dataSuccess(res, sets, success, fail)
				},
				fail: (error) => {
					fail(error.errMsg);
				},
				complete: (res) => {
					if (!tip) {
						uni.hideLoading();
					}
					complete(res);
				}
			});
		}).catch((e) => {
			console.log(e);
			this.tokenError();
		});
	},
	// POST 请求 异步
	post2: function(url, sets, success, fail, complete, isSign, withLoginToken) {
		if (!sets) {
			sets = {};
		}
		if (!success) {
			success = function(res) {}
		}
		if (!fail) {
			fail = function(e) {}
		}

		if (!withLoginToken) {
			withLoginToken = false;
		}

		new Promise(this.getToken.bind(this)).then(() => {
			if (GraceRequestConfig.apiBaseUrl != '') {
				url = GraceRequestConfig.apiBaseUrl + url;
			}
			sets = this.requestInit(sets, withLoginToken, 2);
			if (!sets.header['content-type']) {
				sets.header['content-type'] = GraceRequestConfig.postHeaderDefault;
			}
			if (isSign == true) {
				sets.data = this.sign(sets.data);
			} else if (isSign == 'value') {
				sets.data = this.signValue(sets.data);
			}
			uni.request({
				url: url,
				data: sets.data,
				timeout: sets.timeout,
				dataType: sets.dataType,
				header: sets.header,
				method: 'POST',
				success: (res) => {
					this.dataSuccess(res, sets, success, fail)
				},
				fail: (error) => {
					fail(error.errMsg);
				},
				complete: (res) => {
					if (!complete) {
						uni.hideLoading();
					} else {
						complete(res);
					}
				}
			});
		}).catch((e) => {
			console.log(e);
			this.tokenError();
		});
	},
	// POST 请求 异步
	post3: function(url, sets, success, fail, complete, isSign, withLoginToken) {
		if (!sets) {
			sets = {};
		}
		if (!success) {
			success = function(res) {}
		}
		if (!fail) {
			fail = function(e) {}
		}
		if (!complete) {
			complete = function(res) {}
		}
		if (!withLoginToken) {
			withLoginToken = false;
		}

		new Promise(this.getToken.bind(this)).then(() => {
			if (GraceRequestConfig.apiBaseUrl != '') {
				url = GraceRequestConfig.apiBaseUrl + url;
			}
			sets = this.requestInit(sets, withLoginToken, 2);
			if (!sets.header['content-type']) {
				sets.header['content-type'] = GraceRequestConfig.postHeaderDefault;
			}
			if (isSign == true) {
				sets.data = this.sign(sets.data);
			} else if (isSign == 'value') {
				sets.data = this.signValue(sets.data);
			}
			uni.request({
				url: url,
				data: sets.data,
				timeout: sets.timeout,
				dataType: sets.dataType,
				header: sets.header,
				method: 'POST',
				success: (res) => {
					this.dataSuccess3(res, sets, success, fail)
				},
				fail: (error) => {
					fail(error.errMsg);
				},
				complete: (res) => {
					complete(res);
				}
			});
		}).catch((e) => {
			console.log(e);
			this.tokenError();
		});
	},
	// POST 请求 同步
	postSync: async function(url, sets, isSign, withLoginToken) {
		let res, error;
		if (!withLoginToken) {
			withLoginToken = false;
		}
		return new Promise(this.getToken.bind(this)).then(async () => {
			if (GraceRequestConfig.apiBaseUrl != '') {
				url = GraceRequestConfig.apiBaseUrl + url;
			}
			sets = this.requestInit(sets, withLoginToken, 2);
			if (!sets.header['content-type']) {
				sets.header['content-type'] = GraceRequestConfig.postHeaderDefault;
			}
			if (isSign == true) {
				sets.data = this.sign(sets.data);
			} else if (isSign == 'value') {
				sets.data = this.signValue(sets.data);
			}
			var [error, res] = await uni.request({
				url: url,
				data: sets.data,
				timeout: sets.timeout,
				dataType: sets.dataType,
				header: sets.header,
				method: 'POST'
			});
			if (error != null) {
				return false;
			}
			this.tokenErrorHandle(res);
			return res.data.data;
		}).catch((e) => {
			console.log(e);
			this.tokenError();
			return ['', e];
		});
	},

	// 文件上传
	upload: function(url, filePath, fileType, sets, success, fail, complete, withLoginToken) {
		if (!sets) {
			sets = {};
		}
		if (!success) {
			success = function(res) {}
		}
		if (!fail) {
			fail = function(e) {}
		}
		if (!complete) {
			complete = function(res) {}
		}
		if (!withLoginToken) {
			withLoginToken = false;
		}
		new Promise(this.getToken.bind(this)).then(() => {
			if (GraceRequestConfig.apiBaseUrl != '') {
				url = GraceRequestConfig.apiBaseUrl + url;
			}
			// 初始化 sets
			if (!sets.name) {
				sets.name = 'file';
			}
			if (!sets.header) {
				sets.header = {};
			}
			if (!sets.formData) {
				sets.formData = {};
			}
			if (!sets.header.Authorization) {
				sets.header.Authorization = this.token;
			}
			if (withLoginToken) {
				var loginToken = this.checkLogin();
				if (loginToken) {
					sets.header.loginToken = loginToken;
				}
			}
			// 开始上传
			uni.uploadFile({
				url: url,
				filePath: filePath,
				name: sets.name,
				formData: sets.formData,
				header: sets.header,
				success: (res) => {
					if (res.statusCode == 200) {
						let data = JSON.parse(res.data)
						success(data.data);
					} else {
						this.tokenErrorHandle(res);
					}
				},
				fail: (error) => {
					fail(error);
				},
				complete: (res) => {
					complete(res);
				}
			});
		}).catch((e) => {
			console.log(e);
			this.tokenError();
		});
	},

	// DELETE 请求 异步
	delete: function(url, sets, success, fail, complete, withLoginToken) {
		if (!sets) {
			sets = {};
		}
		if (!success) {
			success = function(res) {}
		}
		if (!fail) {
			fail = function(e) {}
		}
		if (!complete) {
			complete = function(res) {}
		}
		if (!withLoginToken) {
			withLoginToken = false;
		}
		new Promise(this.getToken.bind(this)).then(() => {
			if (GraceRequestConfig.apiBaseUrl != '') {
				url = GraceRequestConfig.apiBaseUrl + url;
			}
			sets = this.requestInit(sets, withLoginToken, 1);
			if (!sets.header['content-type']) {
				sets.header['content-type'] = GraceRequestConfig.postHeaderDefault;
			}
			uni.request({
				url: url,
				data: sets.data,
				timeout: sets.timeout,
				dataType: sets.dataType,
				header: sets.header,
				method: 'DELETE',
				success: (res) => {
					this.dataSuccess(res, sets, success, fail)
				},
				fail: (error) => {
					fail(error.errMsg);
				},
				complete: (res) => {
					uni.hideLoading();
					complete(res);
				}
			});
		}).catch((e) => {
			console.log(e);
			this.tokenError();
		});
	},


	// debug 函数
	debug: function(content) {
		if (!GraceRequestConfig.debug) {
			return;
		}
		console.log(content);
	},

	// token 错误
	tokenError: function() {
		uni.showToast({
			title: "请求失败，请重启应用重试",
			icon: "none"
		});
	},

	// 签名算法
	sign: function(data) {
		var keys = [];
		Object.keys(data).sort().map((key) => {
			keys.push(key);
		});
		keys.push(this.token);
		var sign = md5.md5(keys.join('-'));
		data.gracesign = sign;
		return data;
	},

	// signValue
	signValue: function(data) {
		var vals = [];
		Object.keys(data).sort().map((key) => {
			vals.push(data[key]);
		});
		vals.push(this.token);
		var sign = md5.md5(vals.join('-'));
		data.gracesign = sign;
		return data;
	},

	// 登录检查
	// 登录后在本地保存一个 token
	checkLogin: function(notLoginDo) {
		var loginToken = uni.getStorageSync(GraceRequestConfig.userTokenKeyName);
		if (!loginToken || loginToken == '') {
			loginToken = '';
			if (notLoginDo) {
				uni.showToast({
					title: "请登录",
					icon: "none",
					mask: true
				});
				setTimeout(() => {
					notLoginDo();
				}, 1500);
			}
			return false;
		}
		return loginToken;
	},

	// 跳转到登录页面
	gotoLogin: function(path, opentype) {
		if (!path) {
			path = '../login/login';
		}
		if (!opentype) {
			opentype = 'redirect';
		}
		switch (opentype) {
			case 'redirect':
				uni.redirectTo({
					url: path
				});
				break;
			case 'navigate':
				uni.navigateTo({
					url: path
				});
				break;
			case 'switchTab':
				uni.switchTab({
					url: path
				});
				break;
		}
	},

	// 记录 用户 token 到本地
	// 格式 loginToken-uid
	writeLoginToken: function(token, uid) {
		var loginToken = token + '-' + uid;
		uni.setStorageSync(GraceRequestConfig.userTokenKeyName, loginToken);
		return;
	}

}
